;功能：数值显示（实验10，209页）
;方法：
; 	㊀将es寄存器与字符段绑定mov ax,char	mov es,ax
; 	㊁5937000(5A9768h)	(dx)=005ah	(ax)=9768h	(bx)=0ah
; 	㊂循环：除10，获取余数，转化为数字字符，直至商为0时中断
; 	①除10，(dx)=高16位商 (ax)=低16位商 (bx)=0ah (cx)=0h
; 	②转化为数字字符add cx,30h
; 	③写入字符段mov es:[di],cl
; 	④利用cx判断商是否为0
; 		⒈mov cx,ax	 jcxz 标号	
; 			cx≠0	跳转新一轮循环
; 			cx=0	继续检测dx
; 		⒉mov cx,dx	 jcxz 标号
; 			cx≠0	跳转新一轮循环
; 			cx=0	中断循环
; 	㊃循环：将数字字符串写入显式缓冲区
; 	X/N = int(H/N)*65536 +[rem(H/N)*65536+L]/N
; 	int(H/N)，X/N商高16位
; 	[rem(H/N)*65536+L]/N，X/N低16位商，X/N余数
; 	代码过于杂乱
assume cs:code,ds:char

char segment
	dw 16 dup (0)
char ends

code segment
start:
		mov ax,char
		mov es,ax
		xor di,di

		;被除数低16位、高16位
		mov ax,9768h
		mov dx,005ah
		;除数
		mov bx,10

		;将数字转化为数字字符串
		call ntoc
		
		;显示缓冲区：B8000H--BFFFFH
		mov ax,0b800h
		mov ds,ax
		mov si,640h
		;写入显式缓冲区
		call showstr

		mov ax,4c00h
		int 21h

ntoc:	
		;除10 
		;(ax)=商(X/N商低16位)	(dx)=商(X/N商高16位)
		;(cx)=余数  
		call divten
		add cx,30h
		;写入字符
		mov es:[di],cl
		;利用cx判断商低16位是否为0
		;cx≠0 跳转新一轮循环		cx=0 继续检测dx
		mov cx,ax
		inc di
		jcxz axzero
		;利用jmp指令实现永久循环
		jmp short ntoc

axzero: 
		mov cx,dx
		;利用cx判断商高16位是否为0
		;cx≠0 跳转新一轮循环		cx=0 中断循环
		jcxz dxzero
		jmp short ntoc

dxzero:	
		;数字字符串以0为结尾
		mov byte ptr es:[di],0
		ret

divten:
		;将ax压栈，暂存数据（被除数低16位）
		push ax

		;int(H/N)
		mov ax,dx
		mov dx,0
		;(ax)=H/N商（X/N商高16位）  (dx)=余数
		div bx

		;利用si暂存X/N商高16位
		mov si,ax
		;(dx)=H/N余数高16位  (ax)=X低16位
		pop ax
		;[rem(H/N)*65536+L]/N
		;(ax)=商（X/N商低16位）  (dx)=余数
		div bx

		;(cx)=余数	(dx)=商（X/N商高16位）
		mov cx,dx
		mov dx,si
		ret

showstr:
		;字符串结束字符是0
		dec di
s:
		;低位字节存储字符的ASCII码，高位字节存储字符属性
		mov ax,es:[di]
		;将字符逆序写入显式缓冲区
		mov ds:[si],ax
		mov byte ptr ds:[si+1],02
		;利用cx判断字符串索引是否为0
		mov cx,di
		jcxz ok
		add si,2
		dec di
		jmp short s
ok:
		ret

code ends
end start